﻿using System;
using FluentNHibernate.AutoMap;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Event;
using NHibernate.Tool.hbm2ddl;
using Webshop20.Infrastructure.Persistence.NH.AutoMappings;
using Webshop20.Infrastructure.Persistence.NH.Mappings;
using Webshop20.Infrastructure.Persistence.NH.Interceptors;

namespace Webshop20.Infrastructure.Persistence.NH.Configuration
{
    public class NHibernateSetup
    {
        private static AutoPersistenceModel x;

        public static ISessionFactory GetSessionFactory(string connectionString)
        {
            var y=
                Fluently
                    .Configure()
                    .Database(SetupDatabase(connectionString))
                    .Mappings(SetupAutoMappings())
                    .ExposeConfiguration(UpdateSchema)
                    .BuildSessionFactory();

            x.WriteMappingsTo(@"c:\mappings");

            return y;

        }

        public static ISessionFactory GetSessionFactoryForIntegrationTests(string connectionString)
        {
            return
                Fluently
                    .Configure()
                    .Database(SetupDBForIntegrationTests(connectionString))
                    .Mappings(SetupAutoMappings())
                    .ExposeConfiguration(CreateSchemaForInMemoryDB)
                    .BuildSessionFactory();
        }

        public static SQLiteConfiguration SetupDBForIntegrationTests(string connectionString)
        {
            //connection string has to be : "data source=:memory:"
            return SQLiteConfiguration
                        .Standard
                        .InMemory()
                        .Provider<SQLiteInMemoryTestConnectionProvider>();
        }

        public static MsSqlConfiguration SetupDatabase(string connectionString)
        {
            return 
            MsSqlConfiguration
                .MsSql2005
                .ConnectionString(connString => connString.Is(connectionString));
        }



        public static Action<MappingConfiguration> SetupMappings()
        {
            return m=>m.FluentMappings.AddFromAssemblyOf<CustomerMapping>();
        }

        public static Action<MappingConfiguration> SetupAutoMappings()
        {
            Action<MappingConfiguration> y;

            x = ForCatalog.GetPersistenceModel(); 
           y= m => m.AutoMappings
                            .Add(ForPayment.GetPersistenceModel())
                            .Add(ForProducts.GetPersistenceModel())
                            .Add(ForCustomers.GetPersistenceModel())
                            .Add(x)
                            .Add(ForOrders.GetPersistenceModel())
                            .Add(ForSecurity.GetPersistenceModel())
                            .Add(ForStock.GetPersistenceModel())
                            .Add(ForObjectStore.GetPersistenceModel());
            
            
            return y;

        }

        private static void BuildSchema(NHibernate.Cfg.Configuration config)  
        {  
            var schemaExport = new SchemaExport(config);
           schemaExport.Create(false, true);  
           //schemaExport.Execute(false, false, false, false);

        }

        private static void UpdateSchema(NHibernate.Cfg.Configuration config)
        {
            var schemaExport = new SchemaExport(config);
            schemaExport.Drop(false, true);
            var stack = new IInitializeCollectionEventListener[] { new VisitorPostLoadEventListener(), };
            config.EventListeners.InitializeCollectionEventListeners = stack;


            var schemaUpdate = new SchemaUpdate(config);

            schemaUpdate.Execute(false, true);
        }

        private static void CreateSchemaForInMemoryDB(NHibernate.Cfg.Configuration config)
        {
            var schemaExport = new SchemaExport(config);
            schemaExport.Drop(false, true);
            var stack = new IInitializeCollectionEventListener[] { new VisitorPostLoadEventListener(), };
            config.EventListeners.InitializeCollectionEventListeners = stack;

            schemaExport.SetOutputFile(@"c:\script.sql");
            schemaExport.Create(true, true);
           

        }
  

    }
}
